package com.che.libcommon.api.page;

import android.support.annotation.Nullable;
import android.util.Log;
import com.che.libcommon.api.ApiOptionalResultObserver;
import com.che.libcommon.api.BaseResult;
import com.che.libcommon.api.page.PageList.PageInfo;
import com.che.libcommon.utils.optional.Optional;
import io.reactivex.Single;
import io.reactivex.functions.IntFunction;
import io.reactivex.observers.ResourceObserver;
import io.reactivex.observers.ResourceSingleObserver;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.Subject;
import java.util.List;

public class  Pagination<T>  {

  private PaginationWrapper<T> paginationWrapper;

  //private Subject<List<T>> subject = PublishSubject.create();

  private ResourceSingleObserver<Optional<List<T>>> proxyObserver;
  private ApiOptionalResultObserver<List<T>> realObserver;

  public Pagination(IntFunction<Single<Optional<PageList<T>>>> api) {
    this.paginationWrapper = PaginationWrapper.create(api);
  }


  public Pagination<T> setPaginationWrapper(IntFunction<Single<Optional<PageList<T>>>> api){
    release();
    this.paginationWrapper = PaginationWrapper.create(api);
    return this;
  }


  public void setCallback(ApiOptionalResultObserver<List<T>> realObserver){
    this.realObserver = realObserver;
  }

  public boolean isFirst(){
    return paginationWrapper.isFirst();
  }

  public boolean isEmpty(){
    PageInfo pageInfo = paginationWrapper.pageInfo;


    return pageInfo!=null && pageInfo.total == 0;
  }

  public boolean isEnd(){
    return paginationWrapper.isEnd();
  }

  public boolean isLoading(){
    return paginationWrapper.isRunning;
  }

  public void preLoad(){
    tryLoad(0);
  }


  private boolean canLoad(int position){
    final PageInfo pageInfo = paginationWrapper.pageInfo;
    if(pageInfo == null){
      return true;
    }


    final int currPage = paginationWrapper.getCurrPage();
    final int loadingPage = paginationWrapper.loadingPage;
    final int pageSize= pageInfo.pageSize;
    final int total = pageInfo.total;
    final int totalPage = pageInfo.pageNum;

    final int currMaxPosition = currPage*pageSize;

    if(position >= total || currMaxPosition < position){
      return false;
    }

    if(position > currMaxPosition-5){

      //剩余5个的时候开始加载下一页

      int nextPage = currPage + 1;

      //下一页是最后一页了
      if(nextPage > totalPage){
        return false;
      }

      //下一页正在加载中
      if(nextPage > loadingPage){
        return true;
      }

    }

    return false;
  }

  void tryLoad(int position){
    if(!canLoad(position)){
      return;
    }

    if(proxyObserver != null && !proxyObserver.isDisposed()){
      proxyObserver.dispose();
    }

    proxyObserver = new ResourceSingleObserver<Optional<List<T>>>() {
      @Override
      public void onSuccess(Optional<List<T>> listOptional) {
        realObserver.onSuccess(listOptional);
      }

      @Override
      public void onError(Throwable e) {
        realObserver.onError(e);
      }
    };
    paginationWrapper.next(proxyObserver);

  }


  public void release(){
    if(this.proxyObserver != null){
      this.proxyObserver.dispose();
    }
    paginationWrapper.reset();

  }

}
